#coding=utf-8
import requests
import time
import base58
import ecdsa
import binascii

class Wallet(object):

    def __init__(self):
        print("""       =========================================\n
        Crystal Coin v0.0.1 - BlockChain Research System\n
       =========================================\n\n""")

    def generate_ECDSA_keys(self):
        """This function takes care of creating your private and public (your address) keys.
        It's very important you don't lose any of them or those wallets will be lost
        forever. If someone else get access to your private key, you risk losing your coins.

        private_key: str
        public_ley: base58 (to make it shorter)
        """
        sk = ecdsa.SigningKey.generate(curve=ecdsa.SECP256k1) #this is your sign (private key)
       # private_key = ':'.join(hex(ord(x))[2:] for x in sk.to_string())
        private_key = binascii.hexlify(sk.to_string())

       # private_key = sk.to_string().hex() #convert your private key to hex
        vk = sk.get_verifying_key() #this is your verification key (public key)
        public_key = binascii.hexlify(vk.to_string())
        print("Private key: {0}".format(private_key))
        #we are going to encode the public key to make it shorter
        public_key = base58.b58encode_int(int(public_key,16))
        #using decode() to remove the b'' from the printed string
        print("Wallet address / Public key: {0}".format(public_key.decode()))

        return private_key, public_key

        # sk2 = ecdsa.SigningKey.from_string(private_key.decode('hex'), curve=ecdsa.SECP256k1)
        # signature = base58.b58encode(sk.sign("fuck you"))
        # print signature
        #
        # decode_public_key = base58.b58decode_int(public_key)
        # vk2 = ecdsa.VerifyingKey.from_string(base58.b58decode(public_key),curve=ecdsa.SECP256k1)
        # result = vk2.verify(base58.b58decode(signature),"fuck you")
        # print result

    def wallet_old(self):
        response = 0
        while response not in [1,2,3]:
            response = input("""What do you want to do?
            1. Generate new security
            2. Send coins to another security
            3. Check transactions\n""")
        if response == 1:
            # Generate new security
            print("""=========================================\n
    IMPORTANT: save this credentials or you won't be able to recover your security\n
    =========================================\n""")
            self.generate_ECDSA_keys()
        elif response in "2":
            addr_from = input("From: introduce your security address (public key)\n")
            private_key = input("Introduce your private key\n")
            addr_to = input("To: introduce destination security address\n")
            amount = input("Amount: number stating how much do you want to send\n")
            print("=========================================\n\n")
            print("Is everything correct?\n")
            print("From: {0}\nPrivate Key: {1}\nTo: {2}\nAmount: {3}\n".format(addr_from,private_key,addr_to,amount))
            response = input("y/n\n")
            if response.lower() == "y":
                self.send_transaction(addr_from,private_key,addr_to,amount)
        elif response == "3":
            self.check_transactions()


    def send_transaction(self,addr_from,private_key,addr_to,amount):
        """Sends your transaction to different nodes. Once any of the nodes manage
        to mine a block, your transaction will be added to the blockchain. Dispite
        that, there is a low chance your transaction gets canceled due to other nodes
        having a longer chain. So make sure your transaction is deep into the chain
        before claiming it as approved!
        """
        #for fast debuging REMOVE LATER
        #private_key="181f2448fa4636315032e15bb9cbc3053e10ed062ab0b2680a37cd8cb51f53f2"
        #amount="3000"
        #addr_from="SD5IZAuFixM3PTmkm5ShvLm1tbDNOmVlG7tg6F5r7VHxPNWkNKbzZfa+JdKmfBAIhWs9UKnQLOOL1U+R3WxcsQ=="
        #addr_to="SD5IZAuFixM3PTmkm5ShvLm1tbDNOmVlG7tg6F5r7VHxPNWkNKbzZfa+JdKmfBAIhWs9UKnQLOOL1U+R3WxcsQ=="

        if len(private_key) == 64:
            signature,message = sign_ECDSA_msg(private_key)
            url     = 'http://localhost:5000/txion'
            payload = {"from": addr_from, "to": addr_to, "amount": amount, "signature": signature.decode(), "message": message}
            headers = {"Content-Type": "application/json"}

            res = requests.post(url, json=payload, headers=headers)
            print(res.text)
        else:
            print("Wrong address or key length! Verify and try again.")

    def check_transactions(self):
        """Retrieve the entire blockchain. With this you can check your
        wallets balance. If the blockchain is to long, it may take some time to load.
        """
        res = requests.get('http://localhost:5000/blocks')
        print(res.text)

    def generate_ECDSA_keys(self):
        """This function takes care of creating your private and public (your address) keys.
        It's very important you don't lose any of them or those wallets will be lost
        forever. If someone else get access to your private key, you risk losing your coins.

        private_key: str
        public_ley: base58 (to make it shorter)
        """
        sk = ecdsa.SigningKey.generate(curve=ecdsa.SECP256k1) #this is your sign (private key)
       # private_key = ':'.join(hex(ord(x))[2:] for x in sk.to_string())
        private_key = binascii.hexlify(sk.to_string())

       # private_key = sk.to_string().hex() #convert your private key to hex
        vk = sk.get_verifying_key() #this is your verification key (public key)
        public_key = binascii.hexlify(vk.to_string())
        print("Private key: {0}".format(private_key))
        #we are going to encode the public key to make it shorter
        public_key = base58.b58encode_int(int(public_key,16))
        #using decode() to remove the b'' from the printed string
        print("Wallet address / Public key: {0}".format(public_key.decode()))
        return private_key, public_key

        # sk2 = ecdsa.SigningKey.from_string(private_key.decode('hex'), curve=ecdsa.SECP256k1)
        # signature = base58.b58encode(sk.sign("fuck you"))
        # print signature
        #
        # decode_public_key = base58.b58decode_int(public_key)
        # vk2 = ecdsa.VerifyingKey.from_string(base58.b58decode(public_key),curve=ecdsa.SECP256k1)
        # result = vk2.verify(base58.b58decode(signature),"fuck you")
        # print result

    def sign_ECDSA_msg(self,private_key):
        """Sign the message to be sent
        private_key: must be hex

        return
        signature: base64 (to make it shorter)
        message: str
        """
        #get timestamp, round it, make it string and encode it to bytes
        message=str(round(time.time()))
        bmessage = message.encode()
        sk = ecdsa.SigningKey.from_string(bytes.fromhex(private_key), curve=ecdsa.SECP256k1)
        signature = base58.b58encode(sk.sign(bmessage))
        return signature,message


# if __name__ == '__main__':
#     welcome_msg()
#     generate_ECDSA_keys()
#     #security()
#     input("Press any key to exit...")

